import javax.microedition.lcdui.game.*;
import javax.microedition.lcdui.Image;
import java.util.Random;
public class Monster extends Character {
	int stepChangeDirection=112;
	static boolean isFound;
	Random rand = new Random();
	int iMove = -1;
	int iTimeDie=8;
	public int m_iAI = 1;
	public static int m_iStepCounter = 0;
	boolean isChangedAI2=true;
	int isTimeChangeAI21=0;//if <48 frame when just change AI to 2 from 1, so suitable condition is't change again AI=2.
	int inTimeChangeAI=0;//if > 84 frame(~ 7s, if don't hit supPerman will change m_iAI to 2 from 1
	boolean isChagedAI12=false;// true nghia la quai loai 1 chuyen den quai loai 2
	public Monster(int Blood, int x_character, int y_character, int AI, Image image, int FrameW, int FrameH , int[] sequence, int dir)
	{
		super(Blood,x_character,y_character,image, FrameW, FrameH ,sequence,  dir);
	}
	public Monster(Sprite spr)
	{
		super(spr);
	}
	public Monster(Monster sbm)
	{
		super(sbm);		
	}
	public Monster(Image img, int w, int h)
	{
		super(img,w,h);
	}
	public Monster(Sprite spr, int XInMap, int YInMap)
	{
		super(spr, XInMap, YInMap);
	}
	
	//override 
	public void Move(int[][] data){
	//
		if(iInMapX==cGame.s_MainCharacter.iInMapX 
			&&	iInMapY == cGame.s_MainCharacter.iInMapY
			 && cGame.s_MainCharacter.m_iUndeadTime<=0 )
		{
			cGame.s_MainCharacter.m_iBlood--;
			cGame.s_MainCharacter.m_iUndeadTime=3000;			
		}
		if(m_iAI == 0){ // StD_UPid Monster, just go D_UP and D_DOWN
			//System.out.println(m_iDir);	
			if(m_iDir == D_UP && iMove==-1){
				if(CheckNextCellFree(data, D_UP)){
					iMove = m_iDir;	
					this.iInMapY-=1;
				}	
				else m_iDir = rand.nextInt(4);	
			}
			
			if(m_iDir == D_DOWN && iMove==-1){
				if(CheckNextCellFree(data, D_DOWN)){
					iMove = m_iDir;
					this.iInMapY+=1;
				}	
				else m_iDir = rand.nextInt(4);	
			}
			
			if(m_iDir == D_LEFT && iMove==-1){
				if(CheckNextCellFree(data, D_LEFT)){
					iMove = m_iDir;
					this.iInMapX-=1;
				}	
				else m_iDir = rand.nextInt(4);	
				//System.out.println("Qua trai:"+iInMapX);
			}
			
			if(m_iDir == D_RIGHT&& iMove==-1){
				if(CheckNextCellFree(data, D_RIGHT)){
					iMove = m_iDir;
					this.iInMapX+=1;
				}	
				else m_iDir = rand.nextInt(4);		
			}
			
			
			if(iMove!=-1)
			{
				if(m_iDir==D_UP || m_iDir==D_DOWN) m_iCharacterY+= (iMove-2)*m_iSpeed;
				else if(m_iDir==D_LEFT || m_iDir==D_RIGHT) m_iCharacterX -= (iMove-1)*m_iSpeed;
				if((m_iCharacterX==iInMapX*CELL_SIZE) && (m_iCharacterY == iInMapY*CELL_SIZE)) iMove=-1;
					
			//draw sprite			
			if(iSpr==7)
					iSpr=0;
					else iSpr++;				
			this.setFrame(m_iDir*8+iSpr);			
			}		
			
			this.setPosition(m_iCharacterX-8, m_iCharacterY-16);			
			//System.out.println(iInMapX+"**"+iInMapY);
		}
		if(m_iAI == 1){ // Monster, he can go any where in the map
			// He go 60 pixel and then consider(randomly) to change his direction
			if(isChangedAI2==false)isTimeChangeAI21++;
			if(isTimeChangeAI21>=48){isChangedAI2=true;isTimeChangeAI21=0;}
			if(Math.abs(iInMapX-cGame.s_MainCharacter.iInMapX)<=4 && 
			   Math.abs(iInMapY-cGame.s_MainCharacter.iInMapY)<=4 && isChangedAI2)
			   {m_iAI=2;isChagedAI12=true;return;}
			if(stepChangeDirection<=0 && iTimeDie==8) { stepChangeDirection = 112; m_iDir = rand.nextInt(4);}
				
			//System.out.println(m_iDir+"*************");	
			if(m_iDir == D_UP && iMove==-1){
				if(CheckNextCellFree(data, D_UP)){
					iMove = m_iDir;	
					this.iInMapY-=1;					
				}	
				else m_iDir = rand.nextInt(4);	
			}
			
			if(m_iDir == D_DOWN && iMove==-1){
				if(CheckNextCellFree(data, D_DOWN)){
					iMove = m_iDir;
					this.iInMapY+=1;
				}	
				else m_iDir = rand.nextInt(4);	
			}
			
			if(m_iDir == D_LEFT && iMove==-1){
				if(CheckNextCellFree(data, D_LEFT)){
					iMove = m_iDir;
					this.iInMapX-=1;
				}	
				else m_iDir = rand.nextInt(4);					
			}
			
			if(m_iDir == D_RIGHT && iMove==-1){
				if(CheckNextCellFree(data, D_RIGHT)){
					iMove = m_iDir;
					this.iInMapX+=1;
				}	
				else m_iDir = rand.nextInt(4);		
			}
			
			
			if(iMove!=-1 )
			{
				if(m_iDir==D_UP || m_iDir==D_DOWN) m_iCharacterY+= (iMove-2)*2;
				else if(m_iDir==D_LEFT || m_iDir==D_RIGHT) m_iCharacterX -= (iMove-1)*2;
				if((m_iCharacterX==iInMapX*16) && (m_iCharacterY== iInMapY*16) && iTimeDie==8) iMove=-1;
				stepChangeDirection-=2;
					
			
			//draw sprite
			if(iSpr==7)
					iSpr=0;
					else iSpr++;				
			this.setFrame(m_iDir*8+iSpr);
			}
			
			this.setPosition(m_iCharacterX, m_iCharacterY);	
			//System.out.println("Quai vat:"+ iInMapX+"**"+iInMapY);
			
			
																								
		}
		if(m_iAI == 2){	// Intelligent Monster, he always follow the sD_UPer man
		    if(isChagedAI12==true)inTimeChangeAI++;
		    if((Math.abs(iInMapX-cGame.s_MainCharacter.iInMapX)>=6 ||
			   Math.abs(iInMapY-cGame.s_MainCharacter.iInMapY)>=6 || inTimeChangeAI>=120) && isChagedAI12 && iMove==-1)
			   {m_iAI=1;isChangedAI2=false;inTimeChangeAI=0;isChagedAI12=false;inTimeChangeAI=0;stepChangeDirection=112;return;}
			//if(inTimeChangeAI>=84){inTimeChangeAI=0;return;}
			
			BFS(iInMapY*data[0].length+iInMapX, data);	// Purpose: fill the matrix			
			try{
			for(int i=m_iFront+m_iCounter-1;i>m_iFront;i--){
				if(iInMapY*data[0].length+iInMapX == m_arrQueue[i]&&iMove==-1)
				{
					iInMapX = m_arrQueue[i-1]%data[0].length;
					iInMapY = m_arrQueue[i-1]/data[0].length;
					switch (m_arrQueue[i-1] - m_arrQueue[i])
					{
						case 1: iMove = m_iDir = D_RIGHT;
							break;
						case -1: iMove = m_iDir = D_LEFT;
							break;
						case 30: iMove = m_iDir = D_DOWN;
							break;
						case -30:iMove = m_iDir = D_UP;
							break;
						case 50: iMove = m_iDir = D_DOWN;
							break;
						case -50: iMove = m_iDir = D_UP;
							break;
					}
					
				}
			}
			if(iMove!=-1)
			{
				if(m_iDir==D_UP || m_iDir==D_DOWN) m_iCharacterY+= (iMove-2)*2;
				else if(m_iDir==D_LEFT || m_iDir==D_RIGHT) m_iCharacterX -= (iMove-1)*2;
				if((m_iCharacterX==iInMapX*16) && (m_iCharacterY== iInMapY*16) && iTimeDie==8) iMove=-1;
				
				if(iSpr==7)
					iSpr=0;
					else iSpr++;				
				this.setFrame(m_iDir*8+iSpr);
			}
			this.setPosition(m_iCharacterX, m_iCharacterY);	
			}catch(Exception E){ db("eXCEPTION AT AI=2");}
			DeleteQueue();
			//db("\nBFS thanh cong");
		}
		iDepth= m_iCharacterY;		
	}
	
	public int BFS(int start, int[][] data) //Breadth First Searching
	{
		isFound = false;	// If this variable is set to true, it means we haven't found the target yet.
		DeleteQueue();
		//db("Is the queue empty?:"+isQueueEmpty());	
		
		AddQueue(start);
		
		if(m_arSuperMonster == null) 
		m_arSuperMonster = new int[data.length][data[0].length]; // This array is used for monster path finding
		for(int i=0;i<data.length;i++)
			for(int j=0;j<data[0].length;j++)
				if(data[i][j] < 20 || data[i][j]>BOMB) m_arSuperMonster[i][j] = -1; // Copy ItemMap to arrForSuperMonster
				else m_arSuperMonster[i][j] = 0;
			
		while(isQueueEmpty() == false && isFound == false)  // For each element in Queue we reset its adjacent cell value
		{
			int t = m_iFront;
			for(int i=m_iFront;i<m_iFront+m_iCounter;i++)
			{
				FillAdjacent(m_arrQueue[i], m_arSuperMonster); // Reset suitable adjacent cells' value and put them into Queue
				DeleteElement();
			}	
			
		}
		// Set the inadequate(thua??) value to -1
		for(int i=0;i<data.length;i++)
		{	
			for(int j=0;j<data[0].length;j++)
				if(m_arSuperMonster[i][j]==0) m_arSuperMonster[i][j]=-1;
		}
		
		m_arSuperMonster[iInMapY][iInMapX%data[0].length] = 0; // Very important
		if(!isFound)	{//db("Cannot find");
		                }
		else {			
			Reverse(m_arSuperMonster, cGame.s_MainCharacter.iInMapY*m_arSuperMonster[0].length+cGame.s_MainCharacter.iInMapX, iInMapY*m_arSuperMonster[0].length+iInMapX);	// In Reverse we find out one of the paths and save it into an array(Maybe the Queue).
			//PrintQueue();
		}			
		return 0;
	}	
	
	public int FillAdjacent(int i, int[][] m_arSuperMonster)
	{
		int X, Y;
		X = i%m_arSuperMonster[0].length;
		Y = i/m_arSuperMonster[0].length;
		if(X < m_arSuperMonster[0].length - 1 && m_arSuperMonster[Y][X + 1]==0)
		{
			m_arSuperMonster[Y][X+1] = m_arSuperMonster[Y][X] + 1;
			AddQueue((X+1)+Y*m_arSuperMonster[0].length);
			if(cGame.s_MainCharacter.iInMapX == X + 1 && cGame.s_MainCharacter.iInMapY == Y) 
			{
				isFound = true;
				return m_arSuperMonster[Y][X+1];
			}	
		}
		if(X > 0 && m_arSuperMonster[Y][X-1]==0)
		{
			m_arSuperMonster[Y][X-1] = m_arSuperMonster[Y][X] + 1;
			AddQueue((X-1)+(Y*m_arSuperMonster[0].length));
			if(cGame.s_MainCharacter.iInMapX == X - 1 && cGame.s_MainCharacter.iInMapY == Y) 
			{
				isFound = true;
				return m_arSuperMonster[Y][X - 1];
			}	
		}	
		if(Y < m_arSuperMonster.length - 1 && m_arSuperMonster[Y+1][X]==0)
		{
			m_arSuperMonster[Y+1][X] = m_arSuperMonster[Y][X] + 1;
			AddQueue((X+(Y+1)*m_arSuperMonster[0].length));
			if(cGame.s_MainCharacter.iInMapX == X && cGame.s_MainCharacter.iInMapY == Y + 1) 
			{
				isFound = true;
				return m_arSuperMonster[Y+1][X];
			}	
		}
		if(Y > 0 && m_arSuperMonster[Y-1][X]==0)
		{
			m_arSuperMonster[Y-1][X] = m_arSuperMonster[Y][X] + 1;
			AddQueue(X+(Y-1)*m_arSuperMonster[0].length);
			if(cGame.s_MainCharacter.iInMapX == X && cGame.s_MainCharacter.iInMapY == Y - 1) 
			{
				isFound = true;
				return m_arSuperMonster[Y-1][X];
			}	
		}
		
		return 0;
		
	}
	
	public void Reverse(int a[][], int target, int start ){
		//PrintQueue();
		DeleteQueue();
		//PrintQueue();
		int temp, x, y;
		AddQueue(target);
		while(m_arrQueue[m_iFront + m_iCounter - 1] != start){
			temp = m_arrQueue[m_iFront + m_iCounter - 1];
			x = temp%a[0].length;
			y = temp/a[0].length;
			if(y<a.length-1  && a[y+1][x] == a[y][x] - 1){
				AddQueue((y+1)*a[0].length+x);
				  continue;
				
			}
			if(y>0 			 && a[y-1][x] == a[y][x] - 1){
				AddQueue((y-1)*a[0].length+x);			 
				 continue;
			}
			if(x<a[0].length && a[y][x+1] == a[y][x] - 1){
				AddQueue(y*a[0].length+(x+1));
				  continue;
			}
			if(x>0 			 && a[y][x-1] == a[y][x] - 1){
				AddQueue(y*a[0].length+(x-1));
				 continue;
			}			
		}
	}
	public void db(String str){
		System.out.println(str);
	}	
	public void dbno(String str){
		System.out.print(str);
	}
	public void PrintArray2(int[][] data){
		for(int i=0;i<data.length;i++){
			for(int j=0;j<data[0].length;j++)
				System.out.print(data[i][j]+"  ");
			System.out.println();	
		}
	}
	#include "queue.h"
}

